-- Haskore Live!
--
-- David Siegel <djsiegel@seas.upenn.edu>
-- Jonathan Coveney <jcoveney@wharton.upenn.edu>
--
-- PMidiPerformer.hs
--

-- | Module 'PMidiPerformer' contains our default, somewhat dumb Performer
-- instance. It is dumb because it performs by writing MIDI files to disk and
-- playing them with an external executable.
module PMidiPerformer ( T (T)
                      , runTests
                      ) where

import Test.HUnit
import System.Info (os)
import qualified System
import Control.Concurrent (threadDelay)
import Directory (doesFileExist)

import Performer
import qualified Base
import Performance hiding (perform)
import qualified HaskoreUtil as Haskore 

-- | Type representing a PMidiPerformer. Only used to define Performer instance,
-- so there is not much to see here.
data T = T

-- | File in which the performance is stored and played from.
performanceFile = "performance.mid"

instance Performer T where
    -- Perform a Performance by writing it to disk as a midi file, then
    -- playing the midi on disk.
    perform _ p = do
        if os == "linux"
            then performLinux p
            else performMac p

-- | T's perform method on Mac OS X.
performMac :: Performance -> IO ()
performMac p = do
    Haskore.performanceToMidi performanceFile p
    System.system $ "pmidi " ++ performanceFile ++ " 10"
                            -- ++ show (performanceDuration p)
    return ()

-- | T's perform method on Linux.
--
-- MIDI is tough to get working on Linux, so we sometimes have to disable parts
-- or all of this function.
performLinux :: Performance -> IO ()
performLinux p = do
    Haskore.performanceToMidi performanceFile p
    --System.system $ "pmidi " ++ performanceFile
    threadDelay 3000000
    return ()

-- To test PMidiPerformer, we simply perform a Performance with it, and check if
-- the performance file was created. This tests performMac and performLinux,
-- depending on the platform the test is run on.
testPMidiPerformerPerform = TestCase $ do
    System.system $ "rm " ++ performanceFile
    putStrLn "\nTesting PMidiPerformer's perform method. This test has failed if you do not hear music right now."
    T `perform` Haskore.musicToPerformance Base.base
    success <- doesFileExist performanceFile
    assertBool "performance file was not created" True

-- | Runs unit tests.
runTests = runTestTT $
    TestList [ TestLabel "testPMidiPerformerPerform" testPMidiPerformerPerform
             ]
